package pl.streamsoft.currencyApp.model;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;

/**
 * @author streamsoft
 * Klasa reprezentuj�ca walut�
 */

@Entity
@Cacheable
@Cache(region="Currency",usage=CacheConcurrencyStrategy.READ_ONLY)
@NamedQueries({
	@NamedQuery(name="Currency.deleteWhereNameAndCodeAndDateAreLike",query="delete from Currency where name = :name and currencyCode = :code and date = :date"),
	@NamedQuery(name="Currency.deleteAllCurencies",query="delete from Currency"),
	@NamedQuery(name="Currency.gettingAllCurrenciesWhereAvarageRateIsBetween",query="from Currency where averagerate > ? and averagerate < ?"),
	@NamedQuery(name="Currency.getAllCurrenciesWhereNameMatches",query="from Currency where name like :word"),
	@NamedQuery(name="Currency.getAllWhereDateEq",query="from Currency where date = :date"),
	@NamedQuery(name="Currency.getAllCurrenciesWhereDateIsBetween",query="from Currency where date >= :from and date <= :to"),
	@NamedQuery(name="Currency.getAllCurrenciesWhereCodeAndDateIsLike",query="from Currency where currencyCode = ? and date = ?")
})

@FilterDef(name="matchesFilter", parameters=@ParamDef( name="matchesParam", type="string" ) )
@Filter(name="matchesFilter", condition="name LIKE '%' || :matchesParam || '%'")

@Table(name="Currencies")
public class Currency {
	@Id
	@Column(unique=true, nullable = false)
	private long id;
	private String name;
	private int converter;
	private String currencyCode;
	@Column(precision=6,scale=4)
	private BigDecimal averageRate;
	@Temporal(TemporalType.DATE)
	private Date date;
	
	/*@ManyToMany(mappedBy="currencyList",cascade=CascadeType.PERSIST, fetch=FetchType.LAZY)
	private List<Country> listOfCountries = new ArrayList<Country>();*/

	public Currency(){}
	
	public Currency(String name, int converter, String currencyCode, BigDecimal averageRate, Date date){
		this.name = name;
		this.converter = converter;
		this.currencyCode = currencyCode;
		this.averageRate = averageRate;
		this.date = date;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getConverter() {
		return converter;
	}
	public void setConverter(int converter) {
		this.converter = converter;
	}
	public String getCurrencyCode() {
		return currencyCode;
	}
	public void setCurrencyCode(String currencyCode) {
		this.currencyCode = currencyCode;
	}
	public BigDecimal getAverageRate() {
		return averageRate;
	}
	public void setAverageRate(BigDecimal averageRate) {
		this.averageRate = averageRate;
	}
	
	public Date getDate() {
		return this.date;
	}

	public void setDate(Date date) {
		this.date = date;
	}
	
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
	
	@Override
	public int hashCode() {
		int hash = 7;
		hash = 31 * hash + (null == name ? 0 : name.hashCode());
		hash = 31 * hash + converter;
		hash = 31 * hash + (null == currencyCode ? 0 : currencyCode.hashCode());
		hash = 31 * hash + (null == averageRate ? 0 : averageRate.hashCode());
		hash = 31 * hash + (null == date ? 0 : date.hashCode());
		return hash;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj)
			return true;
		
		if((obj == null) || (obj.getClass() != this.getClass()))
			return false;
		
		Currency currency = (Currency) obj;
		
		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(date);
        Date dateLikeInDB = null;
        try {
			dateLikeInDB = formatter.parse(dateString);
		}
        catch (ParseException e) {e.printStackTrace();}
        
		return (name == currency.name || (name != null && name.equals(currency.name))) &&
				(converter == currency.converter) &&
				(currencyCode == currency.currencyCode || (currencyCode != null && currencyCode.equals(currency.currencyCode))) &&
				(averageRate == currency.averageRate || (averageRate != null && averageRate.equals(currency.averageRate))) &&
				((dateLikeInDB == currency.date || (dateLikeInDB != null && dateLikeInDB.equals(currency.date)))
						|| (this.date == currency.date || (this.date != null && this.date.equals(currency.date))));
	}

	
}
